Pular para o conteúdo principal

1. O K8S

A instalação do Kubernetes é simples e pode ser resolvido com um script e até mesmo ser feita com Ansible, ao menos o setup inicial. Neste caso, fiz manualmente o processo de instalação, para mostrar alguns passos e explicar alguns conceitos.

1.1. Requisitos base

1.1.1. O mínimo

Quando comento com o mínimo, me refiro ao básico que precisa ser feito para que comecemos a instalação e configuração do k8s, seguindo um processo lógico/pratico.

  • Configurar ntpd
  • Configurar SSSD (integração com AD ou LDAP) - se tiver
  • Configurar agente de monitoramento - se tiver
  • SSH
  • Sudoers
  • Grupos
  • Usuários
  • Permissões

1.2. Preparando o Linux

Dividi em três seções:

  • 1.2.1. Passos para todos os nós
  • 1.2.2. Passos para os masters
  • 1.2.3. Passos para os workers

1.2.1. Passos para todos os nós

Essa é a parte que todo mundo quer pular, mas que, se for mal feita, vira dor de cabeça depois. Aqui vamos garantir o básico, o mínimo pra não ferrar tudo quando o kubeadm começar a trabalhar.

Verificar MAC address:

ip link show

Verificar UUID da máquina:

cat /etc/machine-id

Se alguma máquina estiver com o mesmo ID:

rm -f /etc/machine-id
systemd-machine-id-setup

Desativar o swap:

# Verificando
swapon -s

# Desativando
sudo swapoff -a

# Removendo do fstab
sudo sed -i '/swap/d' /etc/fstab

[!NOTE] Nota
Caso queira utilizar a swap, precisa utilizar o seguinte parâmetro:
No kubelet (/etc/default/kubelet), adicionar
failSwapOn: false
ou configurar swapBehavior.

Se tiver um arquivo /swap.img no sistema, apague também, pois isso é um arquivo e ocupa, às vezes, bastante espaço.

1.2.1.1. Ativando overlay e br_netfilter

Explicando rapidamente:

  • OverlayFS: sistema de arquivos em camadas. Escreve por cima, sem mexer na base. Requisito para os containers (docs)
  • br_netfilter: permite que o tráfego de uma bridge passe pelo netfilter, possibilitando a gerência das interfaces de rede dos containers (docs)

Ativando os módulos no boot:

cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF

Carregando os módulos:

sudo modprobe overlay
sudo modprobe br_netfilter

Verificando os módulos:

lsmod | grep overlay
lsmod | grep br_netfilter

1.2.1.2. Parâmetros de rede

Por padrão, o Linux ignora o tráfego que passa por bridges. Só que o CNI (plugin de rede) do Kubernetes precisa ver esse tráfego pra funcionar. Se isso não estiver configurado, você vai perder tempo tentando descobrir por que os pods não se comunicam.

Aqui vai o ajuste obrigatório:

cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-ip6tables = 1
EOF

Ativando sem precisar reiniciar o ambiente:

sudo sysctl --system

1.2.1.3. Configuração dos repositórios necessários

Para o lab, foi necessário instalar as seguintes ferramentas:

  • apt-transport-https: Utiliza repositórios HTTPS, garantindo downloads mais seguros
  • ca-certificates: Gerencia certificados digitais para conexões HTTPS
  • curl: Baixa arquivos e dados via terminal
  • gpg e gnupg2: Gerenciam chaves criptográficas
  • software-properties-common: Ferramenta para adicionar repositórios externos (add-apt-repository)
sudo apt update
sudo apt install -y apt-transport-https ca-certificates curl gpg gnupg2 software-properties-common

Criando a pasta para armazenar as chaves GPG:

sudo mkdir -p /etc/apt/keyrings

Adicionando o repositório Docker no Ubuntu:

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

Adicionando o repositório do Kubernetes (v1.31):

sudo curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.31/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg

echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.31/deb/ /" | sudo tee /etc/apt/sources.list.d/kubernetes.list > /dev/null

Atualizando a base de pacotes:

sudo apt update

1.2.1.4. Instalar containerd

sudo apt install -y containerd.io

containerd.io: Runtime utilizado pelo Kubernetes para gerenciar e executar containers.

1.2.1.5. Configurar o containerd

O containerd é o runtime de containers utilizado pelo Kubernetes para gerenciar a execução de containers em cada nó. Para garantir compatibilidade com o kubelet, é necessário configurar o uso de cgroups com systemd.

Passos:

sudo mkdir -p /etc/containerd

containerd config default | sudo tee /etc/containerd/config.toml > /dev/null

sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml

[!NOTE]
Essa alteração é necessária para que o kubelet funcione corretamente com o containerd em sistemas que utilizam o systemd como gerenciador de serviços (como Ubuntu e Debian). Sem isso, o Kubernetes pode falhar ao iniciar os pods.

Na sequência, o serviço do containerd pode ser iniciado e habilitado com:

sudo systemctl restart containerd
sudo systemctl enable containerd

1.2.1.6. Resumo dos comandos

Todos os comandos desta etapa
# Verificar MAC address
ip link show

# Verificar UUID da máquina
cat /etc/machine-id

# Caso alguma máquina esteja com o mesmo ID
rm -f /etc/machine-id
systemd-machine-id-setup

# Verificar swap
swapon -s

# Desativar swap
sudo swapoff -a

# Remover swap do fstab
sudo sed -i '/swap/d' /etc/fstab

# (Opcional) Apagar o arquivo de swap se existir
sudo rm -f /swap.img

# Configuração para carregar módulos no boot
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF

# Carregamento imediato dos módulos
sudo modprobe overlay
sudo modprobe br_netfilter

# Verificação dos módulos
lsmod | grep overlay
lsmod | grep br_netfilter

# Parâmetros para redirecionamento e inspeção de tráfego bridge
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-ip6tables = 1
EOF

# Aplicar as configurações imediatamente
sudo sysctl --system

1.2.2. Passos para os masters

Este lab foi montado com a versão 1.31.8.

Isso é importante, pois na hora de instalar os pacotes, precisamos garantir que isso seja cumprido corretamente para não ter nenhuma situação inesperada que se torne um impeditivo no futuro.

ComponenteVersãoDetalhes
kube-apiserverv1.31.xTodos os nós de controle (masters) devem rodar exatamente essa versão
kube-controller-managerv1.31.xDeve estar sincronizado com o kube-apiserver
kube-schedulerv1.31.xTambém deve estar na mesma versão
kubeletv1.30.x ou v1.31.xPode estar até uma versão menor atrás, mas nunca à frente
kube-proxyv1.30.x, v1.31.x, v1.32.xPode estar até uma versão acima ou abaixo
kubectlv1.30.x, v1.31.x, v1.32.xFlexível para facilitar administração de diferentes clusters
kubeadmv1.31.xUse a mesma versão do cluster desejado (neste caso, v1.31.x)

Referência: Version skew policy | Kubernetes

Instalar e configurar os componentes principais do Kubernetes

sudo apt install -y  kubectl
apt-mark hold kubelet
systemctl enable kubelet
  • kubelet: Agente que roda em todos os nós, responsável por garantir que os containers estejam em execução conforme definido

1.2.2.1 - Inicializando o cluster

Aqui é onde vem uma "pegada" minha para organização, o k8s no geral pede para baixar os arquivos e ir fazendo o kubectl apply -f qualquercoisa.yml mas com isso o ambiente fica muito desorganizado, aqui vai uma proposta para melhorar isso.

mkdir -p k8s/base/calico \
k8s/base/metallb \
k8s/base/ippool \
k8s/base/networkpolicy \
k8s/base/rbac \
k8s/namespaces/devops/networkpolicy \
k8s/namespaces/devops/rbac \
k8s/namespaces/sistema-x-prod/networkpolicy \
k8s/namespaces/sistema-x-prod/rbac \
k8s/namespaces/modelo/networkpolicy \
k8s/namespaces/modelo/rbac \
k8s/scripts

Assim cada yml utilizado fica no seu lugar, de forma organizada.

Com isto, vamos começar a realizar o download dos ymls e preparar as coisas, aqui apenas fiz o download dos arquivos para depois aplicar as configurações no cluster

CNI - Calico

curl -sSL https://raw.githubusercontent.com/projectcalico/calico/v3.27.0/manifests/calico.yaml -o "/etc/k8s/calico/calico.yaml"

CNI - IPool Calico

cat <<EOF > "/etc/k8s/ippool/default-ippool.yaml"
allation/api#operator.tigera.io/v1.Installation
apiVersion: operator.tigera.io/v1
kind: Installation
metadata:
name: default
spec:
# Configures Calico networking.
calicoNetwork:
ipPools:
- name: default-ipv4-ippool
blockSize: 26
cidr: 10.244.0.0/16
encapsulation: VXLANCrossSubnet
natOutgoing: Enabled
nodeSelector: all()

MetalLB

curl -sSL https://raw.githubusercontent.com/metallb/metallb/v0.14.9/config/manifests/metallb-native.yaml  -o "/etc/k8s/metallb/metallb-native.yaml

Ingress - Nginx

curl -sSL https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.12.2/deploy/static/provider/cloud/deploy.yaml  -o "/etc/k8s/ingress/nginx_deploy.yaml

Baixando as imagens para o containerd

kubeadm config images pull --cri-socket unix:///var/run/containerd/containerd.sock

Inicializando o cluster Atenção ao podnetwork, quando iniciar o calico, precisará utilizar a mesma subnet, caso contrario os pods não inicializarão.

kubeadm init --pod-network-cidr=10.244.0.0/16 --cri-socket unix:///var/run/containerd/containerd.sock --v=5

Configurando kubectl para conectar no cluster

mkdir -p $HOME/.kube
cp /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config

verificando cluster

kubectl get nodes

1.2.2.2 - Configurando o cluster

Caso nao tenha subido de primeira e tudo ficado como ready, valide com:

kubectl get nodes

1.2.3. Passos para os workers

Os workers são os que menos dão trabalho, pois basicamente precisamos instalar o containerd, kubelet e kubeadm e depois incluir no cluster.

Sinceramente, esse deploy do cluster K8s Poderia ser mais Next Next Finish, pra que tanta coisa, poxa, eles poderia fornecer o script que faz isso tudo que estou fazendo na mão rsrssr. mas se quiser tem o kubespray.